﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Identity;
using Volo.Abp.Linq;

namespace WeChat.CMS.OrganizationUnits
{
    [RemoteService(false)]
    public class OrganizationUnitAppService : CMSAppService, IOrganizationUnitAppService
    {
        protected IOrganizationUnitRepository UnitRepository { get; }
        protected OrganizationUnitManager UnitManager { get; }
        protected readonly IAsyncQueryableExecuter _asyncExecuter;
        protected IIdentityUserRepository _identityUserRepository { get; }

        public OrganizationUnitAppService(IOrganizationUnitRepository unitRepository, OrganizationUnitManager unitManager, IIdentityUserRepository identityUserRepository, IAsyncQueryableExecuter asyncExecuter)
        {
            UnitRepository = unitRepository;
            UnitManager = unitManager;
            _identityUserRepository = identityUserRepository;
            _asyncExecuter = asyncExecuter;
        }

        /// <summary>
        /// 获取Tree组织列表
        /// </summary>
        /// <returns></returns>
        public async Task<List<OrganizationUnitTreeDto>> GetOrganizationUnitForTreeAsync(Guid? parnet)
        {
            List<OrganizationUnit> reslist = await UnitRepository.GetListAsync();
            List<OrganizationUnitTreeDto> treelist = await TraverseTreeNewAsync(ObjectMapper.Map<List<OrganizationUnit>, List<OrganizationUnitTreeDto>>(reslist), parnet);

            return treelist;
        }

        public async Task<OrganizationUnitEto> GetOrganizationById(Guid orgId)
        {
            var org = await UnitRepository.FindAsync(orgId);
            return ObjectMapper.Map<OrganizationUnit, OrganizationUnitEto>(org);

        }

        /// <summary>
        /// 获取tree组织为小区管理页面
        /// </summary>
        /// <returns></returns>
        public async Task<List<OrganizationUnitTreeDto>> GetOrganizationUnitForCommuityTreeAsync(Guid userId)
        {
            var user = await _identityUserRepository.FindAsync(userId, true);

            var userorg = user.OrganizationUnits;

            var query = from org in await UnitRepository.GetListAsync()
                        join orguser in userorg
                        on org.Id equals orguser.OrganizationUnitId
                        select org;
            List<OrganizationUnit> reslist = await _asyncExecuter.ToListAsync(query.AsQueryable());

            //判断这个userid 在父节点设置，name这个父节点下的所有的组织都能看到

            //先找到根节点
            var rootList = new List<Guid?>();
            reslist.ForEach(x =>
            {

                var parent = reslist.FirstOrDefault(y => y.Id == x.ParentId);
                if (parent == null)
                    if (rootList.FindIndex(m => m == x.ParentId) == -1)
                    {

                        rootList.Add(x.ParentId);

                    }

            });
            List<OrganizationUnitTreeDto> res = new List<OrganizationUnitTreeDto>();
            foreach (var item in rootList)
            {
                var tmporg = reslist.FirstOrDefault(x => x.Id == item);

                List<OrganizationUnitTreeDto> treelist = await TraverseTreeAsync(ObjectMapper.Map<List<OrganizationUnit>, List<OrganizationUnitTreeDto>>(reslist), item);
                //treelist.Where(x => x.IsCommunity == true).OrderBy(x => x.DisplayName);
                res.AddRange(treelist);

            }

            return res;
        }

        /// <summary>
        /// 新建组织
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<bool> CreateAsync(OrganizationUnitCreateDto input)
        {
            var org = new OrganizationUnit(GuidGenerator.Create(), input.DisplayName, input.ParentId, CurrentTenant.Id);
            await UnitManager.CreateAsync(org);
            return true;
        }

        public async Task MoveAsync(MoveOrganizationUnitDto input)
        {
            var ou = await UnitRepository.FindAsync(input.Id);
            if (ou == null)
            {
                return;
            }
            await UnitManager.MoveAsync(input.Id, input.ParentId);
        }

        /// <summary>
        /// 删除某个节点（如果该节点下有子节点会一并删除）
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<bool> DeleteAsync(Guid id)
        {
            var ou = await UnitRepository.FindAsync(id, false);
            if (ou == null)
            {
                return true;
            }

            await UnitManager.DeleteAsync(id);
            return true;
        }
        /// <summary>
        /// 更新节点信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<bool> UpdateAsync(OrganizationUnitUpdateDto input)
        {
            var ou = await UnitRepository.FindAsync(input.Id, false);
            if (ou == null)
            {
                throw new UserFriendlyException("未找到Id为" + input.Id + "名称为" + input.DisplayName + "的节点");
            }
            ou.DisplayName = input.DisplayName;//单纯的修改组织名称
            await UnitManager.UpdateAsync(ou);

            return true;
        }



        //遍历tree
        protected virtual async Task<List<OrganizationUnitTreeDto>> TraverseTreeAsync(List<OrganizationUnitTreeDto> treeList, Guid? ppid)
        {
            List<OrganizationUnitTreeDto> nodeList = new List<OrganizationUnitTreeDto>();
            var children = treeList.Where(t => t.ParentId == ppid).ToList();
            foreach (var chl in children)
            {
                OrganizationUnitTreeDto node = new OrganizationUnitTreeDto()
                {

                    Id = chl.Id,
                    ParentId = chl.ParentId,
                    DisplayName = chl.DisplayName,
                    UserInOrgCount = (await _identityUserRepository
                    .GetUsersInOrganizationUnitAsync(chl.Id)).Count,
                    Child = await TraverseTreeAsync(treeList, chl.Id)
                };
                nodeList.Add(node);
            }
            return nodeList;
        }

        /// <summary>
        /// 获取所有组织
        /// </summary>
        /// <returns></returns>
        public async Task<List<OrganizationUnitTreeDto>> GetAllListAsync()
        {
            var query = await UnitRepository.GetListAsync();

            var result = query.Where(x => x.IsDeleted == false).ToList();
            return ObjectMapper.Map<List<OrganizationUnit>, List<OrganizationUnitTreeDto>>(result);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="userid"></param>
        /// <returns></returns>
        public async Task<List<OrganizationUnitTreeDto>> GetOrgListByUserIdAsync(Guid userid)
        {
            var user = await _identityUserRepository.FindAsync(userid, true);

            var userorg = user.OrganizationUnits;

            var query = from org in await UnitRepository.GetListAsync()
                        join orguser in userorg
                        on org.Id equals orguser.OrganizationUnitId
                        select org;
            List<OrganizationUnit> reslist = await _asyncExecuter.ToListAsync(query.AsQueryable());
            return ObjectMapper.Map<List<OrganizationUnit>, List<OrganizationUnitTreeDto>>(reslist);
        }


        protected virtual async Task<List<OrganizationUnitTreeDto>> TraverseTreeNewAsync(List<OrganizationUnitTreeDto> treeList, Guid? ppid)
        {
            List<OrganizationUnitTreeDto> nodeList = new List<OrganizationUnitTreeDto>();
            var children = treeList.Where(t => t.ParentId == ppid).ToList();
            foreach (var chl in children)
            {
                var child = await TraverseTreeNewAsync(treeList, chl.Id);
                OrganizationUnitTreeDto node = new OrganizationUnitTreeDto()
                {

                    Id = chl.Id,
                    ParentId = chl.ParentId,
                    DisplayName = chl.DisplayName,
                    UserInOrgCount = (await _identityUserRepository
                    .GetUsersInOrganizationUnitAsync(chl.Id)).Count,
                    Child = child.Count > 0 ? child : null,
                };
                nodeList.Add(node);
            }
            return nodeList;
        }

        /// <summary>
        /// <PagedResultDto<GetUnAddUserOutput>>
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public virtual async Task<PagedResultDto<IdentityUserDto>> GetUnAddUsersAsync(OrganizationUnBindUseRequestDto request)
        {
            OrganizationUnit ou = await UnitRepository.FindAsync(request.OrganizationUnitId);
            if (ou == null)
            {
                throw new UserFriendlyException("未找到Id为" + request.OrganizationUnitId + "的节点");
            }
            else
            {

                var count=await UnitRepository.GetUnaddedUsersCountAsync(ou,request.Filter);
                var list=await UnitRepository.GetUnaddedUsersAsync(ou,maxResultCount:request.MaxResultCount,skipCount:request.SkipCount,filter:request.Filter);
               
                var unbindList=ObjectMapper.Map<List<IdentityUser>,List<IdentityUserDto>>(list);
                return new PagedResultDto<IdentityUserDto>(count, unbindList);
            }
        }
    }

}
